$.fn.position   F
last analyzed

Complexity

Conditions 13
Paths > 20000

Size

Total Lines 136

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 13
nc 294913
nop 1
dl 0
loc 136
rs 2
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like $.fn.position often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
/*
2
 * jQuery UI Position 1.8.15
3
 *
4
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5
 * Dual licensed under the MIT or GPL Version 2 licenses.
6
 * http://jquery.org/license
7
 *
8
 * http://docs.jquery.com/UI/Position
9
 */
10
(function( $, undefined ) {
0 ignored issues
show
Unused Code introduced by
The parameter undefined is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
11
12
$.ui = $.ui || {};
13
14
var horizontalPositions = /left|center|right/,
15
	verticalPositions = /top|center|bottom/,
16
	center = "center",
17
	_position = $.fn.position,
18
	_offset = $.fn.offset;
19
20
$.fn.position = function( options ) {
21
	if ( !options || !options.of ) {
22
		return _position.apply( this, arguments );
23
	}
24
25
	// make a copy, we don't want to modify arguments
26
	options = $.extend( {}, options );
27
28
	var target = $( options.of ),
29
		targetElem = target[0],
30
		collision = ( options.collision || "flip" ).split( " " ),
31
		offset = options.offset ? options.offset.split( " " ) : [ 0, 0 ],
32
		targetWidth,
33
		targetHeight,
34
		basePosition;
35
36
	if ( targetElem.nodeType === 9 ) {
37
		targetWidth = target.width();
38
		targetHeight = target.height();
39
		basePosition = { top: 0, left: 0 };
40
	// TODO: use $.isWindow() in 1.9
41
	} else if ( targetElem.setTimeout ) {
42
		targetWidth = target.width();
43
		targetHeight = target.height();
44
		basePosition = { top: target.scrollTop(), left: target.scrollLeft() };
45
	} else if ( targetElem.preventDefault ) {
46
		// force left top to allow flipping
47
		options.at = "left top";
48
		targetWidth = targetHeight = 0;
49
		basePosition = { top: options.of.pageY, left: options.of.pageX };
50
	} else {
51
		targetWidth = target.outerWidth();
52
		targetHeight = target.outerHeight();
53
		basePosition = target.offset();
54
	}
55
56
	// force my and at to have valid horizontal and veritcal positions
57
	// if a value is missing or invalid, it will be converted to center 
58
	$.each( [ "my", "at" ], function() {
59
		var pos = ( options[this] || "" ).split( " " );
60
		if ( pos.length === 1) {
61
			pos = horizontalPositions.test( pos[0] ) ?
62
				pos.concat( [center] ) :
63
				verticalPositions.test( pos[0] ) ?
64
					[ center ].concat( pos ) :
65
					[ center, center ];
66
		}
67
		pos[ 0 ] = horizontalPositions.test( pos[0] ) ? pos[ 0 ] : center;
68
		pos[ 1 ] = verticalPositions.test( pos[1] ) ? pos[ 1 ] : center;
69
		options[ this ] = pos;
70
	});
71
72
	// normalize collision option
73
	if ( collision.length === 1 ) {
74
		collision[ 1 ] = collision[ 0 ];
75
	}
76
77
	// normalize offset option
78
	offset[ 0 ] = parseInt( offset[0], 10 ) || 0;
79
	if ( offset.length === 1 ) {
80
		offset[ 1 ] = offset[ 0 ];
81
	}
82
	offset[ 1 ] = parseInt( offset[1], 10 ) || 0;
83
84
	if ( options.at[0] === "right" ) {
85
		basePosition.left += targetWidth;
86
	} else if ( options.at[0] === center ) {
87
		basePosition.left += targetWidth / 2;
88
	}
89
90
	if ( options.at[1] === "bottom" ) {
91
		basePosition.top += targetHeight;
92
	} else if ( options.at[1] === center ) {
93
		basePosition.top += targetHeight / 2;
94
	}
95
96
	basePosition.left += offset[ 0 ];
97
	basePosition.top += offset[ 1 ];
98
99
	return this.each(function() {
100
		var elem = $( this ),
101
			elemWidth = elem.outerWidth(),
102
			elemHeight = elem.outerHeight(),
103
			marginLeft = parseInt( $.curCSS( this, "marginLeft", true ) ) || 0,
104
			marginTop = parseInt( $.curCSS( this, "marginTop", true ) ) || 0,
105
			collisionWidth = elemWidth + marginLeft +
106
				( parseInt( $.curCSS( this, "marginRight", true ) ) || 0 ),
107
			collisionHeight = elemHeight + marginTop +
108
				( parseInt( $.curCSS( this, "marginBottom", true ) ) || 0 ),
109
			position = $.extend( {}, basePosition ),
110
			collisionPosition;
111
112
		if ( options.my[0] === "right" ) {
113
			position.left -= elemWidth;
114
		} else if ( options.my[0] === center ) {
115
			position.left -= elemWidth / 2;
116
		}
117
118
		if ( options.my[1] === "bottom" ) {
119
			position.top -= elemHeight;
120
		} else if ( options.my[1] === center ) {
121
			position.top -= elemHeight / 2;
122
		}
123
124
		// prevent fractions (see #5280)
125
		position.left = Math.round( position.left );
126
		position.top = Math.round( position.top );
127
128
		collisionPosition = {
129
			left: position.left - marginLeft,
130
			top: position.top - marginTop
131
		};
132
133
		$.each( [ "left", "top" ], function( i, dir ) {
134
			if ( $.ui.position[ collision[i] ] ) {
135
				$.ui.position[ collision[i] ][ dir ]( position, {
136
					targetWidth: targetWidth,
137
					targetHeight: targetHeight,
138
					elemWidth: elemWidth,
139
					elemHeight: elemHeight,
140
					collisionPosition: collisionPosition,
141
					collisionWidth: collisionWidth,
142
					collisionHeight: collisionHeight,
143
					offset: offset,
144
					my: options.my,
145
					at: options.at
146
				});
147
			}
148
		});
149
150
		if ( $.fn.bgiframe ) {
151
			elem.bgiframe();
152
		}
153
		elem.offset( $.extend( position, { using: options.using } ) );
154
	});
155
};
156
157
$.ui.position = {
158
	fit: {
159
		left: function( position, data ) {
160
			var win = $( window ),
161
				over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft();
162
			position.left = over > 0 ? position.left - over : Math.max( position.left - data.collisionPosition.left, position.left );
163
		},
164
		top: function( position, data ) {
165
			var win = $( window ),
166
				over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop();
167
			position.top = over > 0 ? position.top - over : Math.max( position.top - data.collisionPosition.top, position.top );
168
		}
169
	},
170
171
	flip: {
172
		left: function( position, data ) {
173
			if ( data.at[0] === center ) {
174
				return;
175
			}
176
			var win = $( window ),
177
				over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(),
178
				myOffset = data.my[ 0 ] === "left" ?
179
					-data.elemWidth :
180
					data.my[ 0 ] === "right" ?
181
						data.elemWidth :
182
						0,
183
				atOffset = data.at[ 0 ] === "left" ?
184
					data.targetWidth :
185
					-data.targetWidth,
186
				offset = -2 * data.offset[ 0 ];
187
			position.left += data.collisionPosition.left < 0 ?
188
				myOffset + atOffset + offset :
189
				over > 0 ?
190
					myOffset + atOffset + offset :
191
					0;
192
		},
193
		top: function( position, data ) {
194
			if ( data.at[1] === center ) {
195
				return;
196
			}
197
			var win = $( window ),
198
				over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(),
199
				myOffset = data.my[ 1 ] === "top" ?
200
					-data.elemHeight :
201
					data.my[ 1 ] === "bottom" ?
202
						data.elemHeight :
203
						0,
204
				atOffset = data.at[ 1 ] === "top" ?
205
					data.targetHeight :
206
					-data.targetHeight,
207
				offset = -2 * data.offset[ 1 ];
208
			position.top += data.collisionPosition.top < 0 ?
209
				myOffset + atOffset + offset :
210
				over > 0 ?
211
					myOffset + atOffset + offset :
212
					0;
213
		}
214
	}
215
};
216
217
// offset setter from jQuery 1.4
218
if ( !$.offset.setOffset ) {
219
	$.offset.setOffset = function( elem, options ) {
220
		// set position first, in-case top/left are set even on static elem
221
		if ( /static/.test( $.curCSS( elem, "position" ) ) ) {
222
			elem.style.position = "relative";
223
		}
224
		var curElem   = $( elem ),
225
			curOffset = curElem.offset(),
226
			curTop    = parseInt( $.curCSS( elem, "top",  true ), 10 ) || 0,
227
			curLeft   = parseInt( $.curCSS( elem, "left", true ), 10)  || 0,
228
			props     = {
229
				top:  (options.top  - curOffset.top)  + curTop,
230
				left: (options.left - curOffset.left) + curLeft
231
			};
232
		
233
		if ( 'using' in options ) {
234
			options.using.call( elem, props );
235
		} else {
236
			curElem.css( props );
237
		}
238
	};
239
240
	$.fn.offset = function( options ) {
241
		var elem = this[ 0 ];
242
		if ( !elem || !elem.ownerDocument ) { return null; }
243
		if ( options ) { 
244
			return this.each(function() {
245
				$.offset.setOffset( this, options );
246
			});
247
		}
248
		return _offset.call( this );
249
	};
250
}
251
252
}( jQuery ));
253